package service

import (
	"encoding/json"
	"gitee.com/crack007/goose"
	"gitee.com/crack007/goose/config"
	"gitee.com/crack007/goose/core/web"
	"gitee.com/crack007/goose/helper"
	"github.com/crack007/go-im/src/common/component"
	"github.com/crack007/go-im/src/common/constant"
	"github.com/crack007/go-im/src/common/dao"
	"github.com/crack007/go-im/src/common/entity"
	"github.com/crack007/go-im/src/common/model"
	"github.com/crack007/go-im/src/common/util"
	"github.com/crack007/go-im/src/module/api/dto"
	"math/rand"
	"strconv"
	"time"
)

type userService struct {
}

func (s *userService) Login(loginDto *dto.LoginDto) interface{} {
	userEntity := dao.UserDao.GetByAccount(loginDto.Account)
	if userEntity == nil || userEntity.Password != helper.Md5(loginDto.Password) {
		return web.NewApiException(404, "账号或密码错误")
	}
	loginRespDto := dto.NewLoginRespDto()
	loginRespDto.Id = userEntity.ID
	userModel := model.NewUserModel()
	userModel.Id = loginRespDto.Id
	userModel.Nickname = userEntity.Nickname
	userData, _ := json.Marshal(userModel)
	payloadModel := model.NewJwtPayloadModel(string(userData))
	payloadModel.Exp = config.GetUint32("jwt.expire", 24*3600*7)
	token, err := component.Jwt.GenerateToken(payloadModel)
	if err != nil {
		goose.GetLogger().Error(err)
		return web.NewApiException(500, "系统异常，稍后重试")
	}
	loginRespDto.Token = token
	loginRespDto.Nickname = userEntity.Nickname
	return loginRespDto
}

func (s *userService) Register(registerDto *dto.RegisterDto) interface{} {
	if registerDto.Account == "" {
		return web.NewApiException(500, "账号已被注册")
	}
	userEntity := dao.UserDao.GetByAccount(registerDto.Account)
	if userEntity != nil {
		return web.NewApiException(500, "此账号已被注册")
	}
	userEntity = &entity.UserEntity{}
	id, err := util.ApplyId()
	if err != nil {
		return web.NewApiException(500, err.Error())
	}
	userEntity.UserID = id
	userEntity.Account = registerDto.Account
	userEntity.Password = helper.Md5(registerDto.Password)
	userEntity.CreatedAt = util.GetDatetime()
	userEntity.IsDelete = false
	if registerDto.Nickname == "" {
		rand.Seed(time.Now().Unix())
		registerDto.Nickname = "用户_" + strconv.Itoa(rand.Int())[:7]
	}
	userEntity.Nickname = registerDto.Nickname
	dao.UserDao.Save(userEntity)
	userDto := dto.NewUserDto()
	userDto.Id = userEntity.UserID
	userDto.Nickname = userEntity.Nickname
	return userDto
}

func (s *userService) Search(searchUserDto *dto.SearchUserDto) interface{} {
	userEntity := dao.UserDao.GetByUserId(searchUserDto.Id)
	if userEntity == nil {
		return web.NewApiException(404, "账号不存在")
	}
	userDto := dto.NewUserDto()
	userDto.Id = userEntity.ID
	userDto.Nickname = userEntity.Nickname
	return userDto
}

func (s *userService) AddFriend(addFriendDto *dto.AddFriendDto, userModel *model.UserModel) interface{} {
	toId := addFriendDto.ToId
	fromId := userModel.Id
	if toId == fromId {
		return web.NewApiException(404, "好友不能是自己")
	}
	userEntity := dao.UserDao.GetByUserId(toId)
	if userEntity == nil {
		return web.NewApiException(404, "好友不存在")
	}
	applyEntity := dao.ApplyDao.GetByFromIdAndToId(fromId, toId)
	if applyEntity == nil {
		applyEntity = &entity.ApplyEntity{}
		applyEntity.FromId = fromId
		applyEntity.ToId = toId
		applyEntity.State = 0
		applyEntity.CreatedAt = util.GetDatetime()
		dao.ApplyDao.Save(applyEntity)
		// 添加好友提醒需要推送
		messageDto := dto.NewMessageDto()
		messageDto.Action = constant.ACTION_FRIEND_APPLY
		messageDto.MessageType = constant.MessageText
		messageDto.To = toId
		inviteModel := model.NewInviteModel()
		inviteModel.Nickname = userModel.Nickname
		inviteJson, _ := json.Marshal(inviteModel)
		messageDto.Data = string(inviteJson)
		MessageService.Publish(messageDto, userModel)
	}
	return nil
}
func (s *userService) ListAddFriend(userModel *model.UserModel, listDto *dto.QueryDto) interface{} {
	applyEntities := dao.ApplyDao.ListByToId(userModel.Id, listDto.Page, listDto.Size)
	friendList := dto.NewAddFriendListDto()
	for _, applyEntity := range applyEntities {
		applyDto := dto.NewApplyDto()
		applyDto.User.Id = applyEntity.FromId
		applyDto.Id = applyEntity.ID
		applyDto.State = applyEntity.State
		userEntity := dao.UserDao.GetByUserId(applyEntity.FromId)
		if userEntity != nil {
			applyDto.User.Nickname = userEntity.Nickname
		}
		friendList.List = append(friendList.List, applyDto)
	}
	return friendList
}

func (s *userService) FriendApplyProcess(userModel *model.UserModel, applyDto *dto.ApplyDto) interface{} {
	applyEntity := dao.ApplyDao.GetById(applyDto.Id)
	if applyEntity == nil {
		return web.NewApiException(500, "申请记录不存在")
	}
	if applyEntity.ToId != userModel.Id {
		return web.NewApiException(500, "无权限操作")
	}
	if applyDto.State == 0 {
		return nil
	}
	if applyEntity.State != 0 {
		return nil
	}
	if applyDto.State != 1 && applyDto.State != 2 {
		return web.NewApiException(400, "申请状态异常")
	}
	applyEntity.State = applyDto.State
	dao.ApplyDao.Save(applyEntity)
	// 处理结果通知发起用户
	messageDto := dto.NewMessageDto()
	messageDto.MessageType = constant.MessageText
	messageDto.To = applyEntity.FromId
	messageDto.Action = constant.ACTION_FRIENDAPPLYRESULT
	friendApplyResultModel := model.NewFriendApplyResultModel()
	friendApplyResultModel.Result = applyDto.State

	if applyDto.State == 1 {
		//  通过好友处理
		friendApplyResultModel.Message = "添加好友通过"
		contactEntity := entity.NewContactEntity()
		contactEntity.UserID = userModel.Id
		contactEntity.RelateUserID = applyEntity.FromId
		dao.ContactDao.Save(contactEntity)
		contactEntity = entity.NewContactEntity()
		contactEntity.RelateUserID = userModel.Id
		contactEntity.UserID = applyEntity.FromId
		dao.ContactDao.Save(contactEntity)
		friendApplyResultJson, _ := json.Marshal(friendApplyResultModel)
		messageDto.Data = string(friendApplyResultJson)
		MessageService.Publish(messageDto, userModel)
		return nil
	}
	if applyDto.State == 2 {
		friendApplyResultModel.Message = "添加好友被对方拒绝"
		friendApplyResultJson, _ := json.Marshal(friendApplyResultModel)
		messageDto.Data = string(friendApplyResultJson)
		MessageService.Publish(messageDto, userModel)
	}
	return nil
}
